package com.ruoyi.message.interceptor;

import com.ruoyi.common.core.constant.CacheConstants;
import com.ruoyi.common.core.constant.TokenConstants;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.JwtUtils;
import com.ruoyi.common.core.utils.SpringUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.message.domain.MyPrincipal;
import com.ruoyi.system.api.model.LoginUser;
import com.ruoyi.tws.api.model.LoginDriver;
import io.jsonwebtoken.Claims;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.simp.stomp.StompCommand;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.messaging.support.ChannelInterceptor;
import org.springframework.messaging.support.MessageHeaderAccessor;

/**
 * websocket用户相关渠道拦截器
 */
public class WsUserChannelInterceptor implements ChannelInterceptor {

    public Message<?> preSend(Message<?> message, MessageChannel channel) {
        StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
        // 有客户端连接成功
        if (StompCommand.CONNECT.equals(accessor.getCommand())) {
            String token = accessor.getFirstNativeHeader(TokenConstants.AUTHENTICATION);
            if(token != null && token.startsWith(TokenConstants.PREFIX)) {
                // 如果前端设置了令牌前缀，则裁剪掉前缀
                token = token.replaceFirst(TokenConstants.PREFIX, StringUtils.EMPTY);
                if (StringUtils.isEmpty(token)) {
                    throw new ServiceException("websocket: 令牌不能为空");
                }
                Claims claims = JwtUtils.parseToken(token);
                if (claims == null) {
                    throw new ServiceException("websocket: 令牌已过期或验证不正确！");
                }
                String userkey = JwtUtils.getUserKey(claims);
                RedisService redisService = SpringUtils.getBean(RedisService.class);
                // PC端用户
                if (redisService.hasKey(CacheConstants.LOGIN_TOKEN_KEY + userkey)) {
                    LoginUser user = redisService.getCacheObject(CacheConstants.LOGIN_TOKEN_KEY + userkey);
                    accessor.setUser(new MyPrincipal(user.getUsername()));
//                    System.err.println("PC端用户上线了：" + accessor.getUser().getName());
                } else if(redisService.hasKey(CacheConstants.APP_TOKEN_KEY + userkey)) {
                    // APP端用户
                    LoginDriver loginDriver = redisService.getCacheObject(CacheConstants.APP_TOKEN_KEY + userkey);
                    accessor.setUser(new MyPrincipal(loginDriver.getTelephone()));
//                    System.err.println("APP端用户上线了：" + accessor.getUser().getName());
                } else {
                    throw new ServiceException("websocket: 登录状态已过期");
                }
            } else {
                throw new ServiceException("websocket: The token is illegal");
            }
        } else if (StompCommand.DISCONNECT.equals(accessor.getCommand())) {
            // 有客户端断开连接
//            System.err.println("用户下线了：" + accessor.getUser().getName());
        }
        return message;
    }

}
